using System;

namespace Glue.Internals.Verification
{
    /// <summary>
    /// The most obvious strategy to test this would be to fill one of the objects with values, 
    /// map from that object, and verify that the other object have the values. This we cannot do
    /// since we have no guaranties that we are allowed to set the values on the object we map from.
    /// </summary>
    internal class MapperVerification<LeftType,RightType> : IMapperVerification<LeftType, RightType>
    {
        private readonly Mapping<LeftType, RightType> mapping;
        private readonly Randomizers randomizers = new Randomizers();
        private readonly ConvertibleRandomValues convertibleRandomValues;

        public MapperVerification(Mapping<LeftType, RightType> mapping)
        {
            this.mapping = mapping;
            convertibleRandomValues = new ConvertibleRandomValues(randomizers);
        }

        public void AddRandomizer(Type type, Func<object> func)
        {
            randomizers.AddRandomizer(type, func);
        }

        public void AssertMapsCorrectlyTowards(RightType rightType)
        {
            new AssertMapsCorrectly(mapping.Relations.GetRelationsTowardsRight(), rightType,
                                    new AssertMapsCorrectlyParameters
                                        {
                                            TheRandomizers = convertibleRandomValues,
                                            GetFromPropertyInfo = (x => x.LeftMember),
                                            GetToPropertyInfo = (x => x.RightMember),
                                            GetNestedRelations = (x=>x.GetRelationsTowardsRight())
                                        }
                ).Assert();
        }

        public void AssertMapsCorrectlyTowards(LeftType leftType)
        {
            new AssertMapsCorrectly(mapping.Relations.GetRelationsTowardsLeft(), leftType,
                                    new AssertMapsCorrectlyParameters
                                        {
                                            TheRandomizers = convertibleRandomValues,
                                            GetFromPropertyInfo = (x => x.RightMember),
                                            GetToPropertyInfo = (x => x.LeftMember),
                                            GetNestedRelations = (x=>x.GetRelationsTowardsLeft())
                                        }
                ).Assert();
        }
    }
}